const goDeep = (obj) => {
    if(!(typeof obj === 'object')) return false
    let typeList = [Date, RegExp, Array, Map, Set, Number, Boolean, String, Object]
    let resultType = ''
    for (let i = 0; i < typeList.length; i++) {
        const item = typeList[i];
        if (obj instanceof item) {
            resultType = item.name
            break
        }
    }
    
    return resultType === 'Array' || resultType === 'Object'
}
// 未解决 Date RegExp 等类型堆类型值
const clone = function(obj: Object | Array<any>, isDeep = false): any {
    if (!isDeep) {
        if (obj instanceof Array) { return [...obj] }
        if (obj instanceof Object) { return {...obj} }
    }
    if (obj instanceof Array) {
        let arr: Array<any> = []
        for (let i = 0; i < obj.length; i++) {
            const item = obj[i];
            arr[i] = goDeep(item) ? clone(item, true) : item
        }
        return arr
    }
    if (obj instanceof Object) {
        let resultObj = {}
        for (const key in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, key)) {
                const item = obj[key];
                resultObj[key] = goDeep(item) ? clone(item, true) : item
            }
        }
        return resultObj
    }
}

let testObj = {
    a: {
        b: [1, 2, 3],
        c: {
            c1: 'string',
            c2: [1,23,4]
        },
        d: true,
        e: null,
        f: undefined,
        g: function() {
            console.log('这是 g');
        }
    },
    h: new Date()
}
const reuslt1 = clone(testObj, true)
reuslt1.a.b.push(99)
reuslt1.h.setFullYear(2)
// console.log('reuslt1.h', typeof reuslt1.h, Object.prototype.toString.call(reuslt1.h).slice(8, -1));

console.log('testObj:', testObj);
console.log('result1: ', reuslt1);

const reuslt2 = clone(testObj)
reuslt2.a.b.push(99)
console.log('testObj:', testObj);
console.log('result2: ', reuslt2);
